// transactions_txn.cpp
// Customizer_Base
// Protea Customizer/Customizer Pro / Business Logic for managing transactions
// Copyright (C) 2003, 2004, 2005 eXegeSys, Inc.
// Copyright (C) 2008 Bruce A. James
//
// This program is part of the Protea Project.
//
// The Protea Project is free software; you can redistribute it and/or modify it 
// under the terms of the GNU General Public License as published by the 
// Free Software Foundation, either version 3 of the License, or (at your 
// option) any later version.
//
// The Protea Project is distributed in the hope that it will be useful, but 
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
// or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
// for more details.
// 
// You should have received a copy of the GNU General Public License along 
// with this program.  If not, see <http://www.gnu.org/licenses/>.
//
// Please send correspondence to:
//
// theproteaproject@gmail.com
//

#include "base_setup.h"

//////////////////////////////////////////////////////////////////////////////
//
// Transaction Transactions :)
//
//////////////////////////////////////////////////////////////////////////////

//@ CHA Review Transaction
//@ COD ReviewTransaction
//@ NUM 27
//@ CRI TRANS_CODE
//@ TAB TRANSACTION_DEFN Write
//
//@ GEN Review Transaction will return transaction information,
//@ GEN along with valid user-exits
//
TRANSACTION_CODE( ReviewTransaction ) 
{
	XCBuffer* TransBuf = NULL;
	XCBuffer* ue_defn = NULL;
	XCBuffer* detail = NULL;
	XCDBStatement* stmt = NULL;

	//@ GRS Start the transaction
	START_TXN( ReviewTransaction );

		//@ Create transaction definition buffers
		TransBuf = App->CreateBuffer( FMT_TRANSACTION_DEFN, false );
		ue_defn = App->CreateBuffer( FMT_USER_EXIT_DEFNS, false );

		//@ Move screen info to transaction buffers
		TransBuf->MoveCorresponding( txnvars.buffer, txnvars.Errors );
		ue_defn->MoveCorresponding( txnvars.buffer, txnvars.Errors );

		txnvars.Errors->Check();

		START_DB_TXN();

			//@ If a TRANS_NUMBER is not supplied, convert TRANS_CODE to TRANS_NBR
			if (txnvars.buffer->GetField( FLD_TRANS_NUMBER )->IsBlank())
				LookupNumberFromName( &txnvars, txnvars.buffer, TransBuf, FLD_TRANS_NUMBER, FLD_TRANS_CODE, FMT_TRANSACTION_DEFN );

			//@ SUB TransactionReview to review the record.
			if (!TransactionRetrieve( TransBuf, &txnvars ))
				txnvars.Errors->Add( ERR_DOESNT_EXIST, SEV_CRITICAL, FLD_TRANS_CODE, 1, 20015 );

			txnvars.buffer->MoveCorresponding( TransBuf, txnvars.Errors );
			App->TransResponse( txnvars.result, txnvars.buffer, TRANS_HEADER_TYPE );

			int child = txnvars.buffer->GetChildFormat();
			if (child) {
				detail = App->CreateBuffer( child, true );

				// Load the user exit list for this transaction
				stmt = UserExitList( ue_defn, &txnvars );
				while (!stmt->Eof()) {
					detail->MoveCorresponding( ue_defn, txnvars.Errors, true );
					App->TransResponse( txnvars.result, detail, TRANS_DETAIL_TYPE );
					stmt->MoveNext();
				};
			};
		END_DB_TXN();

	CLEANUP_TXN();
		App->CleanupObjects( 4, &TransBuf, &ue_defn, &detail, &stmt );
	END_TXN();
	//@ GRE End the transaction
};




//
//@ CHA RevTransactions
//@ COD RevTransactions
//@ NUM 190
//@ CRI APPL_NBR
//@ TAB TRANSACTION_DEFN Read
//
//@ GEN RevTransactions returns a list of currently available transactions
//
TRANSACTION_CODE( RevTransactions ) {
	XCBuffer* TransBuf = NULL;
	XCBuffer* detail = NULL;
	XCDBStatement* stmt = NULL;

	XCField* start = NULL;
	XCField* finish = NULL;
	XCField* partial = NULL;

	//@ GRS Start the transaction
	START_TXN( RevTransactions );
		XCSQLGen* query = txnvars.query;

		//@ Create format descriptor buffer
		TransBuf = App->CreateBuffer( FMT_TRANSACTION_DEFN, false );

		//@ Move screen info to transaction buffer
		TransBuf->MoveCorresponding( txnvars.buffer, txnvars.Errors );

		//@ Start the database transaction
		START_DB_TXN();
			XCCompare comptemp[5];
			XCField* list[6];
			int fcount = 0;

			//@ SUB ValidateAppNumber ensure that we have a valid application number
			ValidateAppNumber( &txnvars );

			TransBuf->DebugDump();
			App->TransResponse( txnvars.result, txnvars.buffer, TRANS_HEADER_TYPE );

			int child = txnvars.buffer->GetChildFormat();
			if (child) {
				detail = App->CreateBuffer( child, true );

				// Formulate select statement
				query->MakeSELECT( TransBuf );

				// Select on appl_nbr
				XCField* temp = TransBuf->GetField( FLD_APPL_NBR );
				list[ fcount++ ] = TransBuf->GetField( FLD_APPL_NBR );

				// Search criteria
				temp = txnvars.buffer->GetField( FLD_START_STRING );
				if (temp && !temp->IsBlank()) {
					start = TransBuf->GetField( FLD_TRANS_CODE )->Clone();
					start->MoveField( temp );
					list[ fcount ] = start;
					comptemp[ fcount++ ].comparison = cmp_greaterthanequals;
				};
				temp = txnvars.buffer->GetField( FLD_FINISH_STRING );
				if (temp && !temp->IsBlank()) {
					finish = TransBuf->GetField( FLD_TRANS_CODE )->Clone();
					finish->MoveField( temp );
					list[ fcount ] = finish;
					comptemp[ fcount++ ].comparison = cmp_lessthanequals;
				};
				temp = txnvars.buffer->GetField( FLD_PARTIAL_STRING );
				if (temp && !temp->IsBlank()) {
					partial = TransBuf->GetField( FLD_TRANS_CODE )->Clone();
					partial->MoveField( temp );
					list[ fcount ] = partial;

					// Is this a partial search, or an exact field?
					if (strchr( temp->GetStringPtr(), '%' ))
						comptemp[ fcount ].comparison = cmp_like;
					fcount++;
				};
				list[ fcount ] = NULL;
				query->AddWHERE( list, comptemp );

				// Execute the query
				stmt = txnvars.dbtxn->ExecuteSQL( query );

				while (!stmt->Eof()) {
					detail->MoveCorresponding( TransBuf, txnvars.Errors );
					App->TransResponse( txnvars.result, detail, TRANS_DETAIL_TYPE );
					stmt->MoveNext();
				};
			};

		END_DB_TXN();

	CLEANUP_TXN();
		App->CleanupObjects( 3, &TransBuf, &detail, &stmt );
	END_TXN();
	//@ GRE End the transaction
};
